package lol.clann.minecraft.springboot.remap.remappers;

import lol.clann.minecraft.springboot.remap.ClassLoaderContext;
import relocate.org.objectweb.asm.ClassReader;
import relocate.org.objectweb.asm.tree.ClassNode;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author pyz
 * @date 2019/7/4 1:21 AM
 */
public class SBPClassRepo {
    private static final SBPClassRepo INSTANCE = new SBPClassRepo();

    private final Map<String, ClassNode> cache = new ConcurrentHashMap<>();

    public static SBPClassRepo getInstance() {
        return INSTANCE;
    }

    public final ClassNode findClass(String internalName) {
        ClassNode fromCache = cache.get(internalName);
        if (fromCache != null) {
            return fromCache;
        }
        ClassNode found = findClass0(internalName);
        if (found != null) {
            cache.put(internalName, found);
            return found;
        }

        return null;
    }

    protected ClassNode findClass0(String internalName) {
        InputStream in = getClassLoder().getResourceAsStream(internalName + ".class");
        if (in == null) {
            return null;
        }
        ClassNode classNode = new ClassNode();
        try {
            new ClassReader(in).accept(classNode, 0);
        } catch (IOException e) {
            return null;
        }
        return classNode;
    }

    protected ClassLoader getClassLoder() {
        ClassLoader cl = ClassLoaderContext.peek();
        if (cl == null) {
            cl = Thread.currentThread().getContextClassLoader();
        }
        if (cl == null) {
            cl = this.getClass().getClassLoader();
        }
        return cl;
    }
}
